package cn.lf.service.impl;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.Objects;

import cn.hutool.core.lang.UUID;
import cn.lf.constant.DelFlagTypeEnum;
import cn.lf.constant.ResponseCodeEnum;
import cn.lf.dto.sys.file.FileDelDTO;
import cn.lf.dto.sys.file.FileUploadDTO;
import cn.lf.dto.sys.file.FileUploadRepDTO;
import cn.lf.dto.sys.file.FileUploadReqDTO;
import cn.lf.entity.FileInfo;
import cn.lf.entity.SysUser;
import cn.lf.exception.SelfException;
import cn.lf.mapper.FileInfoMapper;
import cn.lf.service.IFileInfoService;
import cn.lf.utils.MinioEnhance;
import cn.lf.utils.SnowFlakeUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 文件信息 服务实现类
 * </p>
 *
 * @author guoyy
 * @since 2024-04-11
 */
@Service
class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> implements IFileInfoService {

    @Value("${img_file.pre_url}")
    private String imgFilePreUrl;

    @Value("${img_file.local_file_path}")
    private String imgFileLocalPath;

    @Override
    public FileUploadRepDTO uploadFile(FileUploadReqDTO fileUploadReqDTO) {

        FileUploadRepDTO result = new FileUploadRepDTO();

        SysUser sysUser = (SysUser) SecurityUtils.getSubject().getPrincipal();

        long timestamp = System.currentTimeMillis();

        String path = sysUser.getUserName() + "/" + timestamp + "/";

        if (MinioEnhance.statObject(path)){
            throw new SelfException(ResponseCodeEnum.SYS_ERROR.getCode(),"文件已存在");
        }

        boolean uploadFlag = MinioEnhance.putObject(path+fileUploadReqDTO.getFileName(),fileUploadReqDTO.getFile());

        if (!uploadFlag){
            throw new SelfException(ResponseCodeEnum.SYS_ERROR.getCode(),"网络连接异常，上传失败");
        }

        FileInfo fileInfo = new FileInfo();
        fileInfo.setFileId(UUID.randomUUID().toString());
        fileInfo.setDelFalg(DelFlagTypeEnum.UN_DEL.getCode());
        fileInfo.setCreateBy(sysUser.getUserId());
        fileInfo.setCreateTime(LocalDateTime.now());
        fileInfo.setFilePath(path);
        fileInfo.setFileName(fileUploadReqDTO.getFileName());
        fileInfo.setFileSize(fileUploadReqDTO.getFileSize());

        baseMapper.insert(fileInfo);

        result.setFileId(fileInfo.getFileId());

        try {
            Files.createDirectories(Paths.get(imgFileLocalPath+path));
        } catch (IOException e) {
            e.printStackTrace();
        }

        MinioEnhance.downObjectToPath(path+fileUploadReqDTO.getFileName(),
                imgFileLocalPath+path+fileUploadReqDTO.getFileName());

        String url = imgFilePreUrl + path+fileUploadReqDTO.getFileName();

        result.setFileUrl(url);

        return result;
    }

    @Override
    public void delFile(FileDelDTO fileDelDTO) {

        FileInfo fileInfo = baseMapper.selectById(fileDelDTO.getFileId());

        if (Objects.isNull(fileInfo)){
            throw new SelfException(ResponseCodeEnum.SYS_ERROR.getCode(),"文件不存在");
        }

        fileInfo.setDelFalg(DelFlagTypeEnum.HAVING_DEL.getCode());

        baseMapper.updateById(fileInfo);

        String targetPath = fileInfo.getFilePath()+fileInfo.getFileName();

        boolean delFlag = MinioEnhance.removeObject(targetPath);

        if (!delFlag){
            throw new SelfException(ResponseCodeEnum.SYS_ERROR.getCode(),"找不到对应文件");
        }

    }

    @Override
    public FileUploadRepDTO uploadFileUnParam(FileUploadDTO fileUploadDTO) {
        FileUploadRepDTO result = new FileUploadRepDTO();

        SysUser sysUser = (SysUser) SecurityUtils.getSubject().getPrincipal();

        long timestamp = System.currentTimeMillis();

        String path = sysUser.getUserName() + "/" + timestamp + "/";

        if (MinioEnhance.statObject(path)){
            throw new SelfException(ResponseCodeEnum.SYS_ERROR.getCode(),"文件已存在");
        }

        boolean uploadFlag = MinioEnhance.putObject(path+fileUploadDTO.getFile().getOriginalFilename(),fileUploadDTO.getFile());

        if (!uploadFlag){
            throw new SelfException(ResponseCodeEnum.SYS_ERROR.getCode(),"网络连接异常，上传失败");
        }

        FileInfo fileInfo = new FileInfo();
        fileInfo.setFileId(UUID.randomUUID().toString());
        fileInfo.setDelFalg(DelFlagTypeEnum.UN_DEL.getCode());
        fileInfo.setCreateBy(sysUser.getUserId());
        fileInfo.setCreateTime(LocalDateTime.now());
        fileInfo.setFilePath(path);
        fileInfo.setFileName(fileUploadDTO.getFile().getOriginalFilename());
        fileInfo.setFileSize(Long.valueOf(fileUploadDTO.getFile().getSize()).intValue());

        baseMapper.insert(fileInfo);

        result.setFileId(fileInfo.getFileId());

        try {
            Files.createDirectories(Paths.get(imgFileLocalPath+path));
        } catch (IOException e) {
            e.printStackTrace();
        }

        MinioEnhance.downObjectToPath(path+fileUploadDTO.getFile().getOriginalFilename(),
                imgFileLocalPath+path+fileUploadDTO.getFile().getOriginalFilename());

        String url = imgFilePreUrl + path+fileUploadDTO.getFile().getOriginalFilename();

        result.setFileUrl(url);

        return result;
    }
}